---
title: Migrating to Agno v2.0
sidebarTitle: Agno v2.0 Migration Guide
description: Guide to migrate your Agno applications from v1 to v2.
---

If you have questions during your migration, we can help! Find us on [Discord](https://discord.gg/4MtYHHrgA8) or [Discourse](https://community.agno.com/).

<Tip>
  Reference the [v2.0 Changelog](/how-to/v2-changelog) for the full list of
  changes.
</Tip>

## Installing Agno v2

If you are already using Agno, you can upgrade to v2 by running:
```bash
pip install -U agno
```

Otherwise, you can install the latest version of Agno v2 by running:
```bash
pip install agno
```

## Migrating your Agno DB

If you used our `Storage` or `Memory` functionalities to store Agent sessions and memories in your database, you can start by migrating your tables.

Use our migration script: [`libs/agno/scripts/migrate_to_v2.py`](https://github.com/agno-agi/agno/blob/main/libs/agno/scripts/migrate_to_v2.py)

The script supports PostgreSQL, MySQL, SQLite, and MongoDB. Update the database connection settings, the batch size (useful if you are migrating large tables) in the script and run it.

Notice:

- The script won't cleanup the old tables, in case you still need them.
- The script is idempotent. If something goes wrong or if you stop it mid-run, you can run it again.
- Metrics are automatically converted from v1 to v2 format.

## Migrating your Agno code

Each section here covers a specific framework domain, with before and after examples and detailed explanations where needed.

### 1. Agents and Teams

[Agents](/concepts/agents/overview) and [Teams](/concepts/teams/overview) are the main building blocks in the Agno framework.

Below are some of the v2 updates we have made to the `Agent` and `Team` classes:

1.1. Streaming responses with `arun` now returns an `AsyncIterator`, not a coroutine. This is how you consume the resulting events now, when streaming a run:

```python v2_arun.py
async for event in agent.arun(...):
    ...
```

1.2. The `RunResponse` class is now `RunOutput`. This is the type of the results you get when running an Agent:

```python v2_run_output.py
from agno.run.agent import RunOutput

run_output: RunOutput = agent.run(...)
```

1.3. The events you get when streaming an Agent result have been renamed:
- `RunOutputStartedEvent` → `RunStartedEvent`
- `RunOutputCompletedEvent` → `RunCompletedEvent`
- `RunOutputErrorEvent` → `RunErrorEvent`
- `RunOutputCancelledEvent` → `RunCancelledEvent`
- `RunOutputContinuedEvent` → `RunContinuedEvent`
- `RunOutputPausedEvent` → `RunPausedEvent`
- `RunOutputContentEvent` → `RunContentEvent`

1.4. Similarly, for Team output events:
- `TeamRunOutputStartedEvent` → `TeamRunStartedEvent`
- `TeamRunOutputCompletedEvent` → `TeamRunCompletedEvent`
- `TeamRunOutputErrorEvent` → `TeamRunErrorEvent`
- `TeamRunOutputCancelledEvent` → `TeamRunCancelledEvent`
- `TeamRunOutputContentEvent` → `TeamRunContentEvent`

1.5. The `add_state_in_messages` parameter has been deprecated. Variables in instructions are now resolved automatically by default.
1.6. The `context` parameter has been renamed to `dependencies`.

This is how it looked like on v1:
```python v1_context.py
from agno.agent import Agent

agent = Agent(
    context={"top_stories": get_top_hackernews_stories},
    instructions="Here are the top stories: {top_stories}",
    add_state_in_messages=True,
)
```

This is how it looks like now, on v2:

```python v2_dependencies.py
from agno.agent import Agent

agent = Agent(
    dependencies={"top_stories": get_top_hackernews_stories},
    instructions="Here are the top stories: {top_stories}",
    # resolve_in_context=True by default - no need to set add_state_in_messages
)
```

<Tip>
  See the full list of changes in the [Agent
  Updates](/how-to/v2-changelog#agent-updates) section of the changelog.
</Tip>

### 2. Storage

Storage is used to persist Agent sessions, state and memories in a database.

This is how Storage looks like on v1:

```python v1_storage.py
from agno.agent import Agent
from agno.storage.sqlite import SqliteStorage

storage = SqliteStorage(table_name="agent_sessions", db_file="agno.db", mode="agent")

agent = Agent(storage=storage)
```

These are the changes we have made for v2:

2.1. The `Storage` classes have moved from `agno/storage` to `agno/db`. We will now refer to them as our `Db` classes.
2.2. The `mode` parameter has been deprecated. The same instance can now be used by Agents, Teams and Workflows.

```python v2_storage.py
from agno.agent import Agent
from agno.db.sqlite import SqliteDb

db = SqliteDb(db_file="agno.db")

agent = Agent(db=db)
```

2.3. The `table_name` parameter has been deprecated. One instance now handles multiple tables, you can define their names individually.

```python v2_storage_table_names.py
db = SqliteDb(db_file="agno.db", sessions_table="your_sessions_table_name", ...)
```

These are all the supported tables, each used to persist data related to a specific domain:

```python v2_storage_all_tables.py
db = SqliteDb(
    db_file="agno.db",
    # Table to store your Agent, Team and Workflow sessions and runs
    session_table="your_session_table_name",
    # Table to store all user memories
    memory_table="your_memory_table_name",
    # Table to store all metrics aggregations
    metrics_table="your_metrics_table_name",
    # Table to store all your evaluation data
    eval_table="your_evals_table_name",
    # Table to store all your knowledge content
    knowledge_table="your_knowledge_table_name",
)
```

2.4. Previously running a `Team` would create a team session and sessions for every team member participating in the run. Now, only the `Team` session is created. The runs for the team leader and all members can be found in the `Team` session.

```python v2_storage_team_sessions.py
team.run(...)

team_session = team.get_latest_session()

# The runs for the team leader and all team members are here
team_session.runs
```

<Tip>
  See more changes in the [Storage Updates](/how-to/v2-changelog#storage)
  section of the changelog.
</Tip>

### 3. Memory

Memory gives an Agent the ability to recall relevant information.

This is how Memory looks like on V1:

```python v1_memory.py
from agno.agent import Agent
from agno.memory.v2.db.sqlite import SqliteMemoryDb
from agno.memory.v2.memory import Memory

memory_db = SqliteMemoryDb(table_name="memory", db_file="agno.db")
memory = Memory(db=memory_db)

agent = Agent(memory=memory)
```

These are the changes we have made for v2:

3.1. The `MemoryDb` classes have been deprecated. The main `Db` classes are to be used.
3.2. The `Memory` class has been deprecated. You now just need to set `enable_user_memories=True` on an Agent with a `db` for Memory to work.

```python v2_memory.py
from agno.agent import Agent
from agno.db.sqlite import SqliteDb

db = SqliteDb(db_file="agno.db")

agent = Agent(db=db, enable_user_memories=True)
```

3.3. The generated memories will be stored in the `memories_table`. By default, the `agno_memories` will be used. It will be created if needed. You can also set the memory table like this:

```python v2_memory_set_table.py
db = SqliteDb(db_file="agno.db", memory_table="your_memory_table_name")
```

3.4. The methods you previously had access to through the Memory class, are now direclty available on the relevant `db` object. For example:

```python v2_memory_db_methods.py
agent.get_user_memories(user_id="123")
```

You can find examples for other all other databases and advanced scenarios in the [examples](/examples/concepts/memory) section.

<Tip>
  See more changes in the [Memory Updates](/how-to/v2-changelog#memory)
  section of the changelog.
</Tip>

### 4. Knowledge

Knowledge gives an Agent the ability to search and retrieve relevant, domain-specific information from a knowledge base.

These are the changes we have made for v2:

4.1. `AgentKnowledge` has been deprecated in favor of the new `Knowledge` class.
Along with this, all of the child classes that used `AgentKnowledge` as a base have been removed. Their capabilities are now supported
by default in `Knowledge`. This also means that the correct reader for the content that you are adding is now selected automatically, with
the option to override it at any time.

4.2. The `load()` method and its variations have been replaced by `add_content()`. Content is the building block of any piece of knowledge originating
from any sources. For a full example of the usage, see the [Content Types](/concepts/knowledge/content_types) page.

4.3. `Knowledge` now supports a `contents_db`. This allows the storage and management of every piece of content that is added to your knowledge.
Furthermore, we now support deletion of individual vectors using the `remove_vectors_by_id()`, `remove_vectors_by_name()` and remove_vectors by metadata()`methods.
You can also delete all vectors created by a specific piece of content using`remove_content_by_id()`.

4.4 In order to support the deletion mentioned above, VectorDB tables have been updated. Two new columns, `content_hash` and `content_id` have been added.

4.5. The `retriever` field has been renamed to `knowledge_retriever`.

4.6. The `add_references` method has been renamed to `add_knowledge_to_context`.

**Renamed**

- `retriever` -> `knowledge_retriever`
- `add_references` -> `add_knowledge_to_context`

<Tip>
  See more changes in the [Knowledge Updates](/how-to/v2-changelog#knowledge) section of the changelog.
</Tip>

### 5. Metrics

Metrics are used to understand the usage and consumption related to a Session, a Run or a Message.

These are the changes we have made for v2:

5.1. **Field name changes**:
   - `time` → `duration`
   - `audio_tokens` → `audio_total_tokens`
   - `input_audio_tokens` → `audio_input_tokens`
   - `output_audio_tokens` → `audio_output_tokens`
   - `cached_tokens` → `cache_read_tokens`

5.2. **Deprecated fields** (removed in v2):
   - `prompt_tokens` and `completion_tokens` - replaced by `input_tokens` and `output_tokens`
   - `prompt_tokens_details` and `completion_tokens_details` - detailed info moved to `provider_metrics`

5.3. **New structure**:
   - Provider-specific metrics fields are now inside the `provider_metrics` field
   - A new `additional_metrics` field has been added for custom metrics

<Tip>
  The migration script automatically converts all metrics from v1 to v2 format, including nested metrics in session data.
</Tip>

### 6. Teams

We have refactored the `Team` class to be more flexible and powerful.

The biggest changes is that the `mode` parameter has been deprecated. Instead there are attributes that can be used to control the behavior of the team:
    - `respond_directly` -> If True, the team leader won't process responses from the members and instead will return them directly
    - `delegate_task_to_all_members` -> If True, the team leader will delegate tasks to all members simultaneously, instead of one by one. When running async (using `arun`) members will run concurrently.
    - `determine_input_for_members` -> `True` by default. Set to False if you want to send the run input directly to the member agents without the team leader synthesizing its own input. This is useful if you want to send pydantic model input directly to the member agents.

Here is a quick migration guide:
- If you previously used `mode=coordinate`, this is now the default behaviour and you can use the `Team` without any modifications.
- If you previously used `mode=route`, you can now use `respond_directly=True` and `determine_input_for_members=False` to achieve the same behaviour.
- If you previously used `mode=collaborate`, you can set `delegate_task_to_all_members=True` to achieve the same behaviour.

See the [Team updates](/how-to/v2-changelog#team-updates) section of the changelog for more details.

### 7. Workflows

We have heavily updated our Workflows, aiming to provide top-of-the-line tooling to build agentic systems.

<Tip>
  Make sure to check our [comprehensive migration guide for
  Workflows](/how-to/workflows-migration).
</Tip>

### 7. Apps -> Interfaces

The old "apps" system (`AGUIApp`, `SlackApi`, `WhatsappApi`) has been replaced with a unified interfaces system within AgentOS.

#### Before - Standalone Apps
```python
from agno.app.agui.app import AGUIApp

agui_app = AGUIApp(agent=agent)
app = agui_app.get_app()
agui_app.serve(port=8000)
```

#### After - Unified Interfaces
```python
from agno.os import AgentOS
from agno.os.interfaces.agui import AGUI

agent_os = AgentOS(agents=[agent], interfaces=[AGUI(agent=agent)])
app = agent_os.get_app()
agent_os.serve(port=8000)
```

#### Migration Steps
1. **Update imports**: Replace app imports with interface imports
2. **Use AgentOS**: Wrap agents with `AgentOS` and specify interfaces
3. **Update serving**: Use `agent_os.serve()` instead of `app.serve()`

### 8. Playground -> AgentOS

Our `Playground` has been deprecated. Our new [AgentOS](/agent-os/introduction) offering will substitute all usecases.

See [AgentOS](/agent-os/introduction) for more details!
